package components.brush {
	import UIFree.ObjectEvent;
	import UIFree.command.ICommand;
	import UIFree.command.uif_commandManager;
	import UIFree.components.uif_window;
	
	import UIUtils.uif_tb;
	import UIUtils.uif_util;
	import UIUtils.uif_utilBitmap;
	
	import classes.Commands.c_applyBrush;
	import classes.Commands.c_deleteCommand;
	import classes.Commands.c_enterBrushMode;
	import classes.Commands.c_insertBitmapCommand;
	import classes.c_events;
	import classes.c_uiEvents;
	import classes.c_util;
	
	import components.dialogs.brush.c_brushParams;
	import components.dialogs.brush.c_spotBrushParams;
	import components.dialogs.c_propertyDialog;
	import components.editor.c_baseEditor;
	import components.editor.c_baseElement;
	import components.editor.c_bitmapElement;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	public class c_brushRelease {
		private var _app			: collages;
		private var _tmpBmd			: BitmapData;
		private var _brush			: c_baseBrush;
		private var _brushSpot		: Bitmap;
		private var _prevPoint		: Point;
		private	var _editor			: c_baseEditor;
		private var _selected		: c_bitmapElement;
		private	var _brushDialog	: c_propertyDialog;
		
		public function c_brushRelease(a_app: collages) {
			_app = a_app;
			eventListener();
		}
		
		protected function get This(): c_brushRelease {
			return this;
		}
		
		protected function eventListener(): void {
			function onBrush(e: Event): void {
				var element: c_bitmapElement = _app.getValueEvent(c_events.GETSELECTED) as c_bitmapElement;
				if (!element) {
					_app.noCurrentLayerCreate(function(): void {
						var size: Point = new Point(_app.width * 0.5, _app.height * 0.8);
						var a_image: Bitmap = new Bitmap(new BitmapData(size.x, size.y, true, 0));
						_app.workspace.dispatchEvent(new ObjectEvent(c_events.IMAGELOADCOMPLETE, {
							image: a_image,
							params: null
						}));
						element = _app.getValueEvent(c_events.GETSELECTED) as c_bitmapElement;
						onBrush(e);
					});
					return;
				}
				if (element.visible) {
					var a_brush: c_spotBrush = new c_spotBrush();
					a_brush.color = 0xFFFFFF;
					a_brush.blendMode = BlendMode.NORMAL;
					a_brush.colorTransform = new ColorTransform(1, 1, 1, 1);
					executeCommand(new c_enterBrushMode(element, This, a_brush, new c_brushParams(_app.dialogLayer, a_brush, _app.classes.locale.BRUSHPARAMS)));
				}
			}
			
			_app.workspace.addEventListener(c_uiEvents.BRUSH, onBrush);
			
			_app.workspace.addEventListener(c_uiEvents.ERASER, function (e: Event): void {
				var element: c_bitmapElement = _app.getValueEvent(c_events.GETSELECTED) as c_bitmapElement;
				if (element && element.visible) {
					var a_brush: c_eraserBrush = new c_eraserBrush();
					executeCommand(new c_enterBrushMode(element, This, a_brush, new c_spotBrushParams(_app.dialogLayer, a_brush, _app.classes.locale.BRUSHPARAMS)));
				} else _app.noCurrentLayer();
			});
			
			_app.workspace.addEventListener(c_uiEvents.INTELLBRUSH, function (e: Event): void {
				var element: c_bitmapElement = _app.getValueEvent(c_events.GETSELECTED) as c_bitmapElement;
				if (element && element.visible) {
					var a_brush: c_colorSelectEraser = new c_colorSelectEraser();
					executeCommand(new c_enterBrushMode(element, This, a_brush, new c_spotBrushParams(_app.dialogLayer, a_brush, _app.classes.locale.BRUSHPARAMS)));
				} else _app.noCurrentLayer();
			});
		}
		
		public function enterBrushMode(a_selected: c_bitmapElement, a_brush: c_baseBrush, a_dialog: c_propertyDialog): void {
			doOpenBrushMode(a_selected, a_brush, a_dialog);
		}
		
		public function exitBrushMode(): void {
			if (_brushDialog) {
				_brushDialog.removeEventListener(uif_window.CLOSEWINDOW, doCloseDialog);
				_brushDialog.close();
				closeBrushMode();
			}
		}
		
		protected function doOpenBrushMode(a_selected: c_bitmapElement, a_brush: c_baseBrush, a_dialog: c_propertyDialog): void {
			if (_selected) exitBrushMode();
			_selected 		= a_selected;
			_editor 		= a_selected.editor;
			_brush			= a_brush;
			_brushDialog	= a_dialog;
						
			_brushDialog.show();
			_brushDialog.addEvent(Event.CHANGE, function(e: Event): void {
				updateBrushSpot();
			});
			
			_brushDialog.addEvent(uif_window.CLOSEWINDOW, doCloseDialog);
			
			_editor.addEvent(MouseEvent.MOUSE_DOWN, doMouseDown);
			_app.stage.addEventListener(MouseEvent.MOUSE_UP, doMouseUp);
			_editor.addEvent(MouseEvent.MOUSE_MOVE, doMouseMove);
			
			_app.workspace.addEventListener(c_events.CHANGECURRENTELEMENT, doChangeCurrentElement);
			
			_brushSpot = new Bitmap();
			_brushSpot.blendMode = BlendMode.INVERT;
			_selected.editor.addChild(_brushSpot);
			//_selected.addChild(_brushSpot);
			
			_editor.dragRect.look = true;
			updateBrushSpot();			
		}
		
		protected function get brushMode(): Boolean {
			return _selected != null;
		}
		
		protected function doChangeCurrentElement(e: Event): void {
			_brushDialog.close();
		}
		
		protected function doCloseDialog(e: Event): void {
			checkHoles();
			closeBrushMode();
		}		
		
		protected function checkHoles(): void {
			var spots: Array = uif_tb.searchSpots(_selected.bitmap.bitmapData);
			var _element: c_bitmapElement = _selected;
			if ((spots.length > 0) && c_util.testSpotsOuter(spots, _element.bitmap.bitmapData.rect)) {
				_app.alert(_app.classes.locale.WARNING, _app.classes.locale.BITMAPASHOLES, function(): void {
					//executeCommand(new c_insertBitmapCommand(This, uif_util.EnterHere(getNewElementMaxRect(), new Point(source.width, source.height)), source));
					executeCommand(new c_deleteCommand(_editor, _element));
					_app.workspace.dispatchEvent(new ObjectEvent(c_events.IMAGELOADCOMPLETE, {
						image	: _element.bitmap,
						params	: null
					}));
				}, true);
			}
		}
		
		protected function executeCommand(command: ICommand): void {
			_app.workspace.dispatchEvent(new ObjectEvent(uif_commandManager.EXECUTE, command));
		}
		
		protected function closeBrushMode(): void {
			_app.workspace.removeEventListener(c_events.CHANGECURRENTELEMENT, doChangeCurrentElement);
			
			_editor.removeEventListener(MouseEvent.MOUSE_DOWN, doMouseDown);
			_app.stage.removeEventListener(MouseEvent.MOUSE_UP, doMouseUp);
			_editor.removeEventListener(MouseEvent.MOUSE_MOVE, doMouseMove);
			
			_selected.editor.removeChild(_brushSpot);
			_brushSpot.bitmapData.dispose();
			
			_editor.dragRect.look 	= false;
			_selected 				= null;
			_brushDialog 			= null;
		}
		
		protected function doMouseMove(e: MouseEvent): void {
			if (_tmpBmd && e.buttonDown) _brush.sessionPaintTo(_selected.mousePos);
			_brushSpot.x = _selected.editor.mouseX + _brush.bounds.x;
			_brushSpot.y = _selected.editor.mouseY + _brush.bounds.y;
		}
		
		protected function doMouseDown(e: MouseEvent): void {
			_tmpBmd = new BitmapData(_selected.bitmap.width, _selected.bitmap.height, _selected.bitmap.bitmapData.transparent, 0);
			_tmpBmd.copyPixels(_selected.bitmap.bitmapData, _selected.bitmap.bitmapData.rect, uif_util.NULLPOINT);
			_brush.beginSession(_selected.bitmap.bitmapData, _selected.mousePos);
		}
		
		protected function doMouseUp(e: MouseEvent): void {
			if (_tmpBmd) {
				_brush.endSession();
				executeCommand(new c_applyBrush(_selected, _selected.bitmap.bitmapData.clone(), _tmpBmd));
				_tmpBmd = null;
			}
		}		
		
		protected function updateBrushSpot(): void {
			if (_brushSpot.bitmapData) _brushSpot.bitmapData.dispose();
			_brushSpot.bitmapData = _brush.createStampImage();
		}
	}
}